package main

import (
	"../common"
	logging "github.com/op/go-logging"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"runtime"
)

type Config struct {
	MetricInterval     int      `yaml:"metric_interval"`
	CarbonAddr         string   `yaml:"carbon_addr"`
	CarbonAddrs        []string `yaml:"carbon_addrs"`
	MondoAddr          string   `yaml:"mondo_addr"`
	Metrics            []string `yaml:"metrics"`
	Modules            []string `yaml:"modules"`
	LogLevelStr        string   `yaml:"log_level"`
	LogToFile          bool     `yaml:"log_to_file"`
	DiskMetricTimes    int      `yaml:"disk_metric_times"`
	CheckAliveInterval int      `yaml:"check_alive_interval"`
	RetryTimes         int      `yaml:"reconnect_times"`
	LogLevel           logging.Level
}

var (
	DefaultConfig = Config{
		MetricInterval: 30,
		LogLevel:       logging.INFO,
		LogToFile:      false,
	}

	LEVELS = map[string]logging.Level{
		"critical": logging.CRITICAL,
		"error":    logging.ERROR,
		"warning":  logging.WARNING,
		"notice":   logging.NOTICE,
		"info":     logging.INFO,
		"debug":    logging.DEBUG,
	}

	GOLIA_PROC_ALIAS = "bin/golia"
	GOLIA_CONF_ALIAS = "conf/golia.ini"

	UPDATEABLES = map[string]string{}

	DEFAULT_CONFIG          = "conf/golia.ini"
	DEFAULT_LOG             = "log/golia.log"
	DEFAULT_PID             = "run/golia.pid"
	MAX_SENDER_RESULT_CACHE = 10
)

func init() {
	if runtime.GOOS == "windows" {
		GOLIA_PROC_ALIAS = "bin/golia.exe"
		DEFAULT_CONFIG = "conf\\golia.ini"
		DEFAULT_LOG = "log\\golia.log"
		DEFAULT_PID = "run\\golia.pid"
	}
}

func LoadFile(filename string) (*Config, error) {
	content, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	cfg, err := Load(string(content))
	if err != nil {
		return nil, err
	}
	if proc, err := common.LookPath(); err != nil {
		return nil, err
	} else {
		UPDATEABLES = map[string]string{
			GOLIA_PROC_ALIAS: proc,
			GOLIA_CONF_ALIAS: filename,
		}
	}

	level, ok := LEVELS[cfg.LogLevelStr]
	if !ok {
		level = logging.INFO
	}
	if cfg.CarbonAddr != "" {
		cfg.CarbonAddrs = append(cfg.CarbonAddrs, cfg.CarbonAddr)
	}
	cfg.LogLevel = level
	if cfg.CheckAliveInterval == 0 {
		cfg.CheckAliveInterval = 10
	}
	if cfg.RetryTimes == 0 {
		cfg.RetryTimes = 5
	}
	if cfg.DiskMetricTimes == 0 {
		cfg.DiskMetricTimes = 60
	}

	if len(cfg.Modules) == 0 {
		cfg.Modules = []string{"ChangeDetector", "Heartbeater"}
	}

	return cfg, nil
}

func Load(s string) (*Config, error) {
	cfg := &Config{}
	*cfg = DefaultConfig
	err := yaml.Unmarshal([]byte(s), cfg)
	if err != nil {
		return nil, err
	}
	return cfg, nil
}
